package com.starsky.common.beetlsql.config.dbconfig;

import com.alibaba.druid.pool.DruidDataSource;
import com.starsky.common.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.DefaultNameConversion;
import org.beetl.sql.core.IDAutoGen;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.spring4.BeetlSqlDataSource;
import org.beetl.sql.ext.spring4.BeetlSqlScannerConfigurer;
import org.beetl.sql.ext.spring4.SqlManagerFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: fengyuan
 * @date 2018-12-25 13:38:57
 * @Description TODO 数据库配置
 */
@Slf4j
@Configuration
public class BeetlSqlConfig {

    @Primary
    @Bean(name = "masterDb")
    public DataSource druidDataSourceMaster(Environment env) {

        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(env.getProperty("datasource.master.url"));
        druidDataSource.setUsername(env.getProperty("datasource.master.userName"));
        druidDataSource.setPassword(env.getProperty("datasource.master.pwd"));
        druidDataSource.setDriverClassName(env.getProperty("datasource.master.driver"));
        //druidDataSource配置
        druidDataSource.setMaxActive(Integer.valueOf(env.getProperty("datasource.master.maxActive")));
        druidDataSource.setInitialSize(Integer.valueOf(env.getProperty("datasource.master.initialSize")));
        druidDataSource.setMaxWait(Integer.valueOf(env.getProperty("datasource.master.maxWaitMillis")));
        druidDataSource.setMinIdle(Integer.valueOf(env.getProperty("datasource.master.minIdle")));
        druidDataSource.setTimeBetweenEvictionRunsMillis(Long.valueOf(env.getProperty("datasource.master.timeBetweenEvictionRunsMillis")));
        druidDataSource.setMinEvictableIdleTimeMillis(Long.valueOf(env.getProperty("datasource.master.minEvictableIdleTimeMillis")));
        druidDataSource.setValidationQuery(env.getProperty("datasource.master.validationQuery"));
        druidDataSource.setTestWhileIdle(Boolean.valueOf(env.getProperty("datasource.master.testWhileIdle")));
        druidDataSource.setTestOnBorrow(Boolean.valueOf(env.getProperty("datasource.master.testOnBorrow")));
        druidDataSource.setTestOnReturn(Boolean.valueOf(env.getProperty("datasource.master.testOnReturn")));
        druidDataSource.setPoolPreparedStatements(Boolean.valueOf(env.getProperty("datasource.master.poolPreparedStatements")));
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(Integer.valueOf(env.getProperty("datasource.master.maxPoolPreparedStatementPerConnectionSize")));
        druidDataSource.setUseGlobalDataSourceStat(Boolean.valueOf(env.getProperty("datasource.master.useGlobalDataSourceStat")));
        try {
            druidDataSource.setFilters(env.getProperty("datasource.master.filters"));
        } catch (SQLException e) {
            log.error("druid configuration initialization filter: " + e);
        }
        druidDataSource.setConnectionProperties(env.getProperty("datasource.master.connectionProperties"));
        return druidDataSource;
    }

//    @Bean(name = "slaveDb")
//    public DataSource druidDataSourceSlave(Environment env) {
//        DruidDataSource druidDataSource = new DruidDataSource();
//        druidDataSource.setUrl(env.getProperty("datasource.slave.url"));
//        druidDataSource.setUsername(env.getProperty("datasource.slave.userName"));
//        druidDataSource.setPassword(env.getProperty("datasource.slave.pwd"));
//        druidDataSource.setDriverClassName(env.getProperty("datasource.slave.driver"));
//        //druidDataSource配置
//        druidDataSource.setMaxActive(Integer.valueOf(env.getProperty("datasource.slave.maxActive")));
//        druidDataSource.setInitialSize(Integer.valueOf(env.getProperty("datasource.slave.initialSize")));
//        druidDataSource.setMaxWait(Integer.valueOf(env.getProperty("datasource.slave.maxWaitMillis")));
//        druidDataSource.setMinIdle(Integer.valueOf(env.getProperty("datasource.slave.minIdle")));
//        druidDataSource.setTimeBetweenEvictionRunsMillis(Long.valueOf(env.getProperty("datasource.slave.timeBetweenEvictionRunsMillis")));
//        druidDataSource.setMinEvictableIdleTimeMillis(Long.valueOf(env.getProperty("datasource.slave.minEvictableIdleTimeMillis")));
//        druidDataSource.setValidationQuery(env.getProperty("datasource.slave.validationQuery"));
//        druidDataSource.setTestWhileIdle(Boolean.valueOf(env.getProperty("datasource.slave.testWhileIdle")));
//        druidDataSource.setTestOnBorrow(Boolean.valueOf(env.getProperty("datasource.slave.testOnBorrow")));
//        druidDataSource.setTestOnReturn(Boolean.valueOf(env.getProperty("datasource.slave.testOnReturn")));
//        druidDataSource.setPoolPreparedStatements(Boolean.valueOf(env.getProperty("datasource.slave.poolPreparedStatements")));
//        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(Integer.valueOf(env.getProperty("datasource.slave.maxPoolPreparedStatementPerConnectionSize")));
//        druidDataSource.setUseGlobalDataSourceStat(Boolean.valueOf(env.getProperty("datasource.slave.useGlobalDataSourceStat")));
//        try {
//            druidDataSource.setFilters(env.getProperty("datasource.slave.filters"));
//        } catch (SQLException e) {
//            log.error("druid configuration initialization filter: " + e);
//        }
//        druidDataSource.setConnectionProperties(env.getProperty("datasource.slave.connectionProperties"));
//        return druidDataSource;
//    }

    @Bean(name = "source")
    public BeetlSqlDataSource sourceDataSource(@Qualifier("masterDb") DataSource masterDb
                                               /*, @Qualifier("slaveDb") DataSource slaveDb*/) {
        BeetlSqlDataSource source = new BeetlSqlDataSource();
        source.setMasterSource(masterDb);
//        source.setSlaves(new DataSource[]{slaveDb});
        return source;
    }

    @Bean(name = "sqlManagerFactoryBean")
    @Primary
    public SqlManagerFactoryBean getSqlManagerFactoryBean(@Qualifier("source") BeetlSqlDataSource source, Environment env) {        //设置主键生成规则
        Map<String, IDAutoGen> map = new HashMap<>();
        map.put("UuidPk", params -> UUIDUtils.getUUID());
        //创建SqlManager
        SqlManagerFactoryBean factory = new SqlManagerFactoryBean();
        factory.setDbStyle(new MySqlStyle());
        factory.setSqlLoader(new ClasspathLoader("/sql"));
        factory.setCs(source);
        factory.setNc(new DefaultNameConversion());
        String property = env.getProperty("logging.level.root");
        property = (StringUtils.isNoneBlank(property) ? property.toLowerCase() : "");
        if ("debug".equals(property)) {
            factory.setInterceptors(new Interceptor[]{new DebugInterceptor()});
        }
        factory.setIdAutoGens(map);
        return factory;
    }

    @Bean(name = "beetlSqlScannerConfigurer")
    public BeetlSqlScannerConfigurer getBeetlSqlScannerConfigurer() {
        BeetlSqlScannerConfigurer conf = new BeetlSqlScannerConfigurer();
        conf.setBasePackage("com.**.**.dao");
        conf.setDaoSuffix("Dao");
        conf.setSqlManagerFactoryBeanName("sqlManagerFactoryBean");
        return conf;
    }

}
